package com.zhu.classfile.attribute;
import com.zhu.classfile.constant.ConstantInfo;
import com.zhu.classfile.constant.ConstantPool;
import com.zhu.classfile.constant.base.*;

import java.nio.ByteBuffer;

/**
 * ConstantValue 属性
 *
 * 用于表示 static final 基本类型或 String 字段的初始值。
 * 注意：仅用于类字段（static + final），且值必须是编译期常量。
 *
 * 结构：
 * ConstantValue_attribute {
 *     u2 attribute_name_index;
 *     u4 attribute_length;
 *     u2 constantvalue_index;
 * }
 */
public class ConstantValueAttribute implements AttributeInfo {

    // 指向常量池的引用（用于后续解析 constantvalue_index）
    private ConstantPool constantPool;

    // 指向常量池中字面量项的索引
    // 可能指向：CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long,
    //           CONSTANT_Double, CONSTANT_Utf8 (用于 String)
    private int constantValueIndex;

    /**
     * 构造函数：只传入 cp，不传 index
     *
     * @param constantPool 常量池引用
     */
    public ConstantValueAttribute(ConstantPool constantPool) {
        this.constantPool = constantPool;
    }

    /**
     * 获取常量值
     *
     * 返回实际的 Java 值，如 Integer, Float, Long, Double, String
     * 如果索引无效或类型不支持，抛出异常
     *
     * @return 字段的初始值
     */
    public Object getConstantValue() {
        ConstantInfo constantInfo = constantPool.get(constantValueIndex);

        switch (constantInfo.getTag()) {
            case CONSTANT_Integer:
                return ((ConstantIntegerInfo) constantInfo).getValue();
            case CONSTANT_Float:
                return ((ConstantFloatInfo) constantInfo).getValue();
            case CONSTANT_Long:
                return ((ConstantLongInfo) constantInfo).getValue();
            case CONSTANT_Double:
                return ((ConstantDoubleInfo) constantInfo).getValue();
            case CONSTANT_Utf8:
                return ((ConstantUtf8Info) constantInfo).getValue();
            default:
                throw new IllegalArgumentException("Unsupported constant type: " + constantInfo.getTag());
        }
    }


    // ------------------------
    // 实现 AttributeInfo 接口
    // ------------------------

    /**
     * 从 ByteBuffer 中读取属性内容
     *
     * @param reader ByteBuffer 读取器
     */
    @Override
    public void readInfo(ByteBuffer reader) {
        this.constantValueIndex = Short.toUnsignedInt(reader.getShort());
    }
    // ------------------------
    // 辅助方法（可选）
    // ------------------------

    /**
     * 获取原始索引（调试用）
     */
    public int getConstantValueIndex() {
        return constantValueIndex;
    }
}